package com.nbsaas.boot.quartz.controller;

import com.nbsaas.boot.quartz.api.apis.SchedulingTaskApi;
import com.nbsaas.boot.quartz.api.domain.request.SchedulingTaskRequest;
import com.nbsaas.boot.quartz.api.domain.response.SchedulingTaskResponse;
import com.nbsaas.boot.quartz.api.domain.simple.SchedulingTaskSimple;
import com.nbsaas.boot.quartz.jobs.HttpJob;
import com.nbsaas.boot.rest.filter.Filter;
import com.nbsaas.boot.rest.response.MapResponse;
import com.nbsaas.boot.rest.response.ResponseObject;
import jakarta.annotation.Resource;
import org.quartz.*;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class TaskController {

    @Resource
    private Scheduler scheduler;

    @Resource
    private SchedulingTaskApi scheduleTaskApi;

    @Resource
    private ApplicationContext applicationContext;

    @RequestMapping("/start")
    public ResponseObject<?> start() throws SchedulerException {
        if (scheduler.isStarted()) {
            scheduler.start();
        }
        return ResponseObject.success();
    }

    @RequestMapping("/pause")
    public ResponseObject<?> pause() throws SchedulerException {
        scheduler.pauseAll();
        return ResponseObject.success();
    }


    @RequestMapping("/resume")
    public ResponseObject<?> resume() throws SchedulerException {
        scheduler.resumeAll();
        return ResponseObject.success();
    }

    @RequestMapping("/getMetaData")
    public ResponseObject<?> getMetaData() throws SchedulerException {
        ResponseObject<SchedulerMetaData> result = new ResponseObject<>();
        result.setData(scheduler.getMetaData());
        return result;
    }

    @RequestMapping("/nextTime")
    public ResponseObject<?> nextTime(@RequestBody SchedulingTaskRequest request) {
        ResponseObject<MapResponse> result = new ResponseObject<>();
        ResponseObject<SchedulingTaskResponse> res = scheduleTaskApi.view(request);
        if (res.getCode() != 200) {
            return res;
        }
        SchedulingTaskResponse task = res.getData();
        try {
            MapResponse map = new MapResponse();
            JobDetail jobDetail = JobBuilder.newJob(HttpJob.class)
                    .withIdentity("job" + task.getId(), "group" + task.getId())
                    .build();
            scheduler.triggerJob(jobDetail.getKey());
            List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobDetail.getKey());
            for (Trigger t : triggers) {
                // 检查是否为待执行状态
                Trigger.TriggerState state = scheduler.getTriggerState(t.getKey());
                if (state == Trigger.TriggerState.NORMAL || state == Trigger.TriggerState.PAUSED) {
                    map.put("nextTime", t.getNextFireTime());
                    map.put("id", t.getKey().getName());
                    map.put("name", t.getKey().getName());
                    result.setData(map);
                }
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }

        return result;
    }

    @RequestMapping("/exeTask")
    public ResponseObject<?> exeTask(@RequestBody SchedulingTaskRequest request) {
        ResponseObject<?> result = new ResponseObject<>();
        ResponseObject<SchedulingTaskResponse> res = scheduleTaskApi.view(request);
        if (res.getCode() != 200) {
            return res;
        }
        SchedulingTaskResponse task = res.getData();
        try {
            JobDetail jobDetail = JobBuilder.newJob(HttpJob.class)
                    .withIdentity("job" + task.getId(), "group" + task.getId())
                    .usingJobData("url", task.getUrl())
                    .usingJobData("id", task.getId()).build();
            jobDetail.getJobDataMap().put("applicationContext", applicationContext);
            scheduler.triggerJob(jobDetail.getKey());
        } catch (SchedulerException e) {
            e.printStackTrace();
        }

        return result;
    }

    @RequestMapping("/loadTasks")
    public ResponseObject<?> loadTasks() throws SchedulerException {

        if (!scheduler.isStarted()) {
            scheduler.resumeAll();
        }

        List<SchedulingTaskSimple> tasks = scheduleTaskApi.listData(Filter.ge("id", 0L));
        if (tasks != null) {
            for (SchedulingTaskSimple task : tasks) {


                Trigger trigger = TriggerBuilder.newTrigger().withSchedule(CronScheduleBuilder.cronSchedule(task.getCronExpression()))
                        .withIdentity("trigger" + task.getId(), "group" + task.getId()).build();
                if (!scheduler.checkExists(trigger.getKey())) {

                    JobDetail jobDetail = JobBuilder.newJob(HttpJob.class)
                            .withIdentity("job" + task.getId(), "group" + task.getId())
                            .usingJobData("url", task.getUrl())
                            .usingJobData("id", task.getId()).build();
                    jobDetail.getJobDataMap().put("applicationContext", applicationContext);


                    scheduler.scheduleJob(jobDetail, trigger);
                }
            }
        }

        return ResponseObject.success();
    }


    @RequestMapping("/cleanTask")
    public ResponseObject<?> cleanTask() throws SchedulerException {
        ResponseObject<?> result = new ResponseObject<>();
        scheduler.clear();
        return result;
    }
}
